<template>
  <div class="table-box dict">
    <div class="add-parent">
      <ProTable
        ref="proTable"
        title="字典父级列表"
        row-key="id"
        :indent="20"
        :columns="columnParent"
        :pagination="false"
        :is-show-search="false"
        highlight-current-row
        :request-api="getTableList"
        :data-callback="dataCallback"
        @row-click="rowClick"
      >
        <!-- 表格 header 按钮 -->
        <template #tableHeader>
          <el-button v-auth="'add'" type="primary" @click="openDrawer('新增', 1)">新增 </el-button>
          <el-button v-auth="'update'" type="primary" @click="openDrawer('编辑', 1, parentRow)">编辑 </el-button>
          <el-button v-auth="'delete'" type="primary" @click="deleteD(parentRow)">删除 </el-button>
        </template>
      </ProTable>
    </div>
    <div class="add-child">
      <ProTable
        ref="proTableChild"
        title="字典子集列表"
        row-key="id"
        :data="dictChildrenList"
        :indent="20"
        :columns="columns"
        :pagination="false"
        :request-auto="false"
        :is-show-search="false"
        lazy
        :load="expandHanlde"
        :tree-props="{ children: 'children', hasChildren: 'hasChild' }"
      >
        <!-- 表格 header 按钮 -->
        <template #tableHeader>
          <el-button type="primary" @click="openDrawer(`新增-${parentRow.name}`, 2, { parentId: parentRow.id })">
            新增
          </el-button>
        </template>
        <!-- 菜单图标 -->
        <template #icon="scope">
          <img :src="`${urlResource}${scope.row.icon}`" alt="" width="20" height="20" v-if="scope.row.icon" />
          <span v-else>--</span>
        </template>
        <!-- 菜单操作 -->
        <template #operation="scope">
          <el-button
            v-auth="'add'"
            type="primary"
            link
            @click="openDrawer(`新增-${scope.row.name}`, 3, { parentId: scope.row.id })"
          >
            新增
          </el-button>
          <el-button v-auth="'update'" type="primary" link @click="openDrawer(`编辑-${scope.row.name}`, 3, scope.row)">
            编辑
          </el-button>
          <el-button v-auth="'delete'" type="primary" link @click="deleteChild(scope.row)"> 删除 </el-button>
        </template>
      </ProTable>
    </div>
    <dictDrawer ref="drawerRef" />
  </div>
</template>

<script setup lang="ts" name="menuMange">
import { Dict } from "@/api/interface";
import { ref, onMounted, watch, reactive, nextTick } from "vue"; // nextTick
import { ColumnProps } from "@/components/ProTable/interface";
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";
import ProTable from "@/components/ProTable/index.vue";
import { addDictList, editDictList, delDictList, getDictList, getDict } from "@/api/modules/sys"; // getDict
import dictDrawer from "./dictDrawer.vue";
import { useHandleData } from "@/hooks/useHandleData";
import { findParent, differenceByProperty } from "@/utils"; // getCurrentNode, unionByProperty
// import { ElMessage } from "element-plus";

const proTable = ref();
const proTableChild = ref();
const urlResource = window?.staticConfig.urlResource;
let initParam = reactive({});
let parentRow: Partial<Dict.ResDictList> = ref();
const dictChildrenList = ref([]);
const allData = ref([]);
const treeRefreshMap = new Map();
// 默认第一条数据选中
const setCurrent = (row: Dict.ResDictList) => {
  proTable.value?.element?.setCurrentRow(row);
  parentRow.value = row;
};
// 折叠

// 单击行
const rowClick = (row: Dict.ResDictList, column: TableColumnCtx<Dict.ResDictList>) => {
  if (column.property == "radio" || column.property == "operation") return;
  parentRow.value = row;
  // ElMessage.success("当前行被点击了！");
};
// 表格配置项
const columns: ColumnProps[] = [
  // { type: "index", label: "#", width: 150 },
  // { type: "expand", label: "Expand", width: 100 },
  { prop: "id", label: "ID", width: 250, isShow: false },
  { prop: "name", label: "字典项名称", align: "left", search: { el: "input" } },
  { prop: "nameEn", label: "字典项名称(英文)", search: { el: "input" }, isShow: false },
  { prop: "value", label: "值" },
  {
    prop: "icon",
    label: "图标",
    isShow: false
  },
  { prop: "remark", label: "备注", width: 300, search: { el: "input" } },
  { prop: "operation", label: "操作", width: 300, fixed: "right" }
];

const columnParent: ColumnProps[] = [
  // { type: "expand", label: "Expand", width: 100 },
  // { type: "index", label: "#", width: 40 },
  { prop: "id", label: "ID", width: 150, isShow: false },
  { prop: "name", label: "字典名称", align: "left", search: { el: "input" } }
  // { prop: "operation", label: "操作", width: 220, fixed: "right" }
];

// 获取数据list
// dataCallback 是对于返回的表格数据做处理，如果你后台返回的数据不是 list && total && pageNum && pageSize 这些字段，那么你可以在这里进行处理成这些字段
// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
const dataCallback = (data: any) => {
  if (data.length) {
    setCurrent(data[0]);
  }
  return data;
};

// 如果你想在请求之前对当前请求参数做一些操作，可以自定义如下函数：params 为当前所有的请求参数（包括分页），最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
const getTableList = () => {
  return getDictList();
};
const getTabChildList = (params: any) => {
  return getDict(params);
};
// 展开
const expandHanlde = async (row: Dict.ResDictList, treeNode: unknown, resolve) => {
  let { data } = await getDict({ parentId: row.id });
  const parent = findParent(allData.value, row.id);
  if (parent) {
    parent.children = data;
    treeNode.children = data;
  }
  if (!treeRefreshMap.has(row.id)) {
    treeRefreshMap.set(row.id, { row, treeNode, resolve });
  }
  resolve(data);
};
// 新增
const appendChild = async (params: Dict.ResDictList) => {
  // 添加数据
  const parent = findParent(allData.value, params.parentId);
  if (parent) {
    parent.children = parent.children ? parent.children : [];
    if (parent.children.find(item => item.id === params.id)) {
      // 编辑
      const index = parent.children.findIndex(item => item.id === params.id);
      const children = parent.children[index]?.children || [];
      params.children = children;
      parent.children.splice(index, 1, params);
    } else {
      // 新增
      parent.children.unshift(params);
    }
  } else {
    if (allData.value.find(item => item.id === params.id)) {
      const index = allData.value.findIndex(item => item.id === params.id);
      const children = allData.value[index]?.children || [];
      params.children = children;
      allData.value.splice(index, 1, params);
    } else {
      allData.value.unshift(params);
    }
  }
  refreshData(params);
};
// 删除字典或者字典项
const deleteD = async (params: Partial<Dict.ResDictList> = {}) => {
  await useHandleData(delDictList, { id: params.id }, `删除【${params.name}】字典`);
  proTable.value?.getTableList();
};
const deleteChild = async (params: Partial<Dict.ResDictList> = {}) => {
  const result = await useHandleData(delDictList, { id: params.id }, `删除【${params.name}】`);
  if (result) {
    if (params.parentId === parentRow.value.id) {
      const index = allData.value.findIndex(item => item.id === params.id);
      allData.value.splice(index, 1);
    } else {
      const parent = findParent(allData.value, params.parentId);
      if (parent && parent.children) {
        const index = parent.children.findIndex(child => child.id === params.id);
        parent.children.splice(index, 1);
      }
    }
    refreshData();
  }
};
// 刷新数据
async function refreshData(expandRow: Dict.ResDictList | undefined = undefined) {
  console.log(expandRow, differenceByProperty, nextTick);
  // dictChildrenList.value = allData.value;
  if (expandRow) {
    // 子项点击发布或者取消发布时，更新子项方法
    // const map = treeRefreshMap.get(expandRow.parentId);
    // if (map) {
    //   const { row, treeNode, resolve } = map;
    //   proTableChild.value?.element?.load(row, treeNode, resolve);
    // }
    async function expandFn(parentId) {
      const parent = findParent(allData.value, parentId);
      if (parent) {
        let { data } = await getDict({ parentId: parent.id });
        const list = differenceByProperty(data, parent.children, "id");
        list.forEach(item => {
          parent.children.push(item);
        });
        // console.log(parent);
        // expandFn(parent.parentId);
        nextTick(() => {
          console.log(proTableChild.value?.element?.store);
          const store = proTableChild.value?.element?.store;
          store.states.lazyTreeNodeMap.value[parent.id] = parent.children;
          // proTableChild.value?.element.store.loadOrToggle(parent);
          nextTick(() => {
            proTableChild.value?.element?.toggleRowExpansion(parent, true);
          });
        });
      }
    }
    expandFn(expandRow.parentId);
  }
  // if (!expandRow) return;
  // const parent = findParent(allData.value, expandRow.parentId);
  // proTableChild.value?.element?.load(parent, parent.children, resolve);
  // console.log(proTableChild.value?.element);
  // const data = getCurrentNode(allData.value, expandRow.id);
  // console.log(data, allData.value);
  // if (data) proTableChild.value?.element?.toggleRowExpansion(data, true);
  // console.log(expandRow);
  // dictChildrenList.value = JSON.parse(JSON.stringify(allData.value));
  // expandHanlde(expandRow);
  // nextTick(() => {
  //   proTableChild.value?.element?.doLayout();
  //
  // });
}

// 打开 drawer(新增、查看、编辑)
const drawerRef = ref<InstanceType<typeof dictDrawer> | null>(null);
const openDrawer = (title: string, type?: number, row: Partial<Dict.ResDictList> = {}) => {
  let paramRow = JSON.parse(JSON.stringify(row));
  if (paramRow.children) {
    delete paramRow.children;
  }
  const params = {
    title,
    isView: title === "查看",
    row: { ...paramRow },
    type,
    api: title.split("-")[0] === "新增" ? addDictList : title.split("-")[0] === "编辑" ? editDictList : undefined,
    getTableList: type == 1 ? proTable.value?.getTableList : appendChild
  };
  drawerRef.value?.acceptParams(params);
};
const initRequest = async params => {
  const { data } = await getTabChildList(params);
  allData.value = dictChildrenList.value = data;
};
// onMounted
onMounted(() => {});
// watch
watch(parentRow, async val => {
  initParam.parentId = val.id;
  initRequest(initParam);
});
</script>

<style lang="scss">
.el-table .warning-row,
.el-table .warning-row .el-table-fixed-column--right,
.el-table .warning-row .el-table-fixed-column--left {
  background-color: var(--el-color-warning-light-9);
}
.el-table .success-row,
.el-table .success-row .el-table-fixed-column--right,
.el-table .success-row .el-table-fixed-column--left {
  background-color: var(--el-color-success-light-9);
}
.dict {
  flex: 1;
  flex-flow: row nowrap;
  .add-parent {
    // flex: 1.2;

    width: 260px;
    margin-right: 10px;
  }
  .add-child {
    flex: 1;
    width: 0;
  }
}
</style>
